package com.ruoyi.web.controller.tool;

import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;

import javax.imageio.ImageIO;

/**
 * swagger 用户测试方法
 *
 * @author ruoyi
 */
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
    private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
    {
        users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
        users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
    }

    @ApiOperation("获取用户列表")
    @GetMapping("/list")
    public R<List<UserEntity>> userList()
    {
        List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
        return R.ok(userList);
    }

    @ApiOperation("获取用户详细")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
    @GetMapping("/{userId}")
    public R<UserEntity> getUser(@PathVariable Integer userId)
    {
        if (!users.isEmpty() && users.containsKey(userId))
        {
            return R.ok(users.get(userId));
        }
        else
        {
            return R.fail("用户不存在");
        }
    }

    @ApiOperation("新增用户")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
        @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
        @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
        @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
    })
    @PostMapping("/save")
    public R<String> save(UserEntity user)
    {
        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
        {
            return R.fail("用户ID不能为空");
        }
        users.put(user.getUserId(), user);
        return R.ok();
    }

    @ApiOperation("更新用户")
    @PutMapping("/update")
    public R<String> update(@RequestBody UserEntity user)
    {
        if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
        {
            return R.fail("用户ID不能为空");
        }
        if (users.isEmpty() || !users.containsKey(user.getUserId()))
        {
            return R.fail("用户不存在");
        }
        users.remove(user.getUserId());
        users.put(user.getUserId(), user);
        return R.ok();
    }

    @ApiOperation("删除用户信息")
    @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
    @DeleteMapping("/{userId}")
    public R<String> delete(@PathVariable Integer userId)
    {
        if (!users.isEmpty() && users.containsKey(userId))
        {
            users.remove(userId);
            return R.ok();
        }
        else
        {
            return R.fail("用户不存在");
        }
    }

    /**
     * 调用微信二维码接口并处理返回
     * @param paramsMap 具体参数下面前端中有体现
     * @return
     * @throws Exception
     */
    @ApiOperation("生成葵花码")
    @PostMapping("/code")
    public AjaxResult getWxaCodeUnLimit(@RequestBody Map<String, Object> paramsMap) throws Exception {
        // 拼装url
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + paramsMap.get("token");
        String jsonString = JSON.toJSONString(paramsMap.get("params"));
        // 调用微信小程序二维码接口，传递接口中需要的参数，并返回为ByteArrayInputStream格式的数据
        ByteArrayInputStream inputStream = this.sendPost(url, jsonString);
        // ByteArrayInputStream转BufferedImage
        BufferedImage wxQrImg = ImageIO.read(inputStream);
        // 用户logo
        URL imgUrl = new URL(paramsMap.get("img").toString());
        InputStream imgInputStream = imgUrl.openStream();
        BufferedImage logoImage = ImageIO.read(imgInputStream);
        // 这里可以随便找个外链图片测试
        // BufferedImage logoImage = ImageIO.read(new URL("imgUrl"));

        // logo图的宽高
        int width = logoImage.getWidth();
        int height = logoImage.getHeight();
        // 保存正方形的边长
        int size = 0;
        // 判断那条边的边更长
        if (width > height) {
            size = height;
        } else {
            size = width;
        }
        // 裁剪：获取正中间的正方形，边长为图片宽的值 后面.size方法必须调用 否则异常
        logoImage = Thumbnails.of(logoImage).sourceRegion(Positions.CENTER, size, size).size(size, size).asBufferedImage();
        // 转成圆形
        logoImage = convertCircular(logoImage);
        // 缩放：放大微信二维码的底图  目的为了减少对用户上传的图片缩放过小图片失真
        wxQrImg = Thumbnails.of(wxQrImg).size(wxQrImg.getHeight() * 2, wxQrImg.getHeight() * 2).asBufferedImage();

        // 使用Graphics2D合并图片
        Graphics2D g2 = null;
        // 读取微信二维码图片
        g2 = wxQrImg.createGraphics();
        // 合并：并设置偏移量，logo图片大小。具体需要自己按照实际的大小调整
        g2.drawImage(logoImage, 177, 177, 290, 290, null);
        g2.dispose();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(wxQrImg, "png", os);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());

        //返回web前端，这里返回的是base64
        byte[] buff = new byte[byteArrayInputStream.available() + 1];
        byteArrayInputStream.read(buff, 0, byteArrayInputStream.available());

        return AjaxResult.success(buff);
    }

    /**
     * 转成圆形
     *
     * @param bufferedImage
     * @return
     * @throws IOException
     */
    public static BufferedImage convertCircular(BufferedImage bufferedImage) throws IOException {
        //透明底的图片
        BufferedImage newbufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
        Graphics2D g2d = newbufferedImage.createGraphics();
        //增加背景透明
        newbufferedImage = g2d.getDeviceConfiguration().createCompatibleImage(bufferedImage.getWidth(), bufferedImage.getHeight(), Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = newbufferedImage.createGraphics();
        //背景透明end

        // 使用 setRenderingHint 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setClip(shape);
        g2d.drawImage(bufferedImage, 0, 0, null);
        // 设置颜色
        g2d.setBackground(Color.green);
        g2d.dispose();
        return newbufferedImage;
    }

    /**
     * 发送http请求访问微信小程序接口获得输入流
     *
     * @param URL
     * @param json
     * @return
     */
    public ByteArrayInputStream sendPost(String URL, String json) {
        InputStream inputStream = null;
        ByteArrayInputStream byteArrayInputStream = null;
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(URL);
        httppost.addHeader("Content-type", "application/json; charset=utf-8");
        httppost.setHeader("Accept", "application/json");
        try {
            StringEntity s = new StringEntity(json, Charset.forName("UTF-8"));
            s.setContentEncoding("UTF-8");
            httppost.setEntity(s);
            HttpResponse response = httpclient.execute(httppost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 获取相应实体
                HttpEntity entity = response.getEntity();
                inputStream = entity.getContent();
                ByteArrayOutputStream outStream = new ByteArrayOutputStream();
                // 创建一个Buffer字符串
                byte[] buffer = new byte[1024];
                // 每次读取的字符串长度，如果为-1，代表全部读取完毕
                int len = 0;
                // 使用一个输入流从buffer里把数据读取出来
                while ((len = inputStream.read(buffer)) != -1) {
                    // 用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                    outStream.write(buffer, 0, len);
                }
                // 关闭输入流
                inputStream.close();
                // 把outStream里的数据写入内存
                byteArrayInputStream = new ByteArrayInputStream(outStream.toByteArray());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return byteArrayInputStream;
    }
}



@ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity
{
    @ApiModelProperty("用户ID")
    private Integer userId;

    @ApiModelProperty("用户名称")
    private String username;

    @ApiModelProperty("用户密码")
    private String password;

    @ApiModelProperty("用户手机")
    private String mobile;

    public UserEntity()
    {

    }

    public UserEntity(Integer userId, String username, String password, String mobile)
    {
        this.userId = userId;
        this.username = username;
        this.password = password;
        this.mobile = mobile;
    }

    public Integer getUserId()
    {
        return userId;
    }

    public void setUserId(Integer userId)
    {
        this.userId = userId;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getMobile()
    {
        return mobile;
    }

    public void setMobile(String mobile)
    {
        this.mobile = mobile;
    }
}
